"""视频控制器"""
import json
import logging
from typing import List, Optional, Dict, Any
from sqlalchemy.orm import Session, joinedload
from sqlalchemy import desc, func
from app.models.video import Video
from app.models.user import User
from app.models.category import Category
from app.models.like import Like
from app.models.favorite import Favorite
from app.schemas.video import VideoResponse, VideoDetailResponse
from app.schemas.common import PageResponse
from app.utils.redis_util import redis_util
import threading

logger = logging.getLogger(__name__)


class VideoController:
    """视频控制器类"""
    
    @staticmethod
    def _get_video_detail_query(db: Session):
        """获取视频详情查询（包含用户信息）"""
        return db.query(
            Video,
            User.username,
            User.nickname,
            User.avatar
        ).join(
            User, Video.user_id == User.id
        ).filter(
            Video.status == 1
        )
    
    @staticmethod
    def get_recommended_videos(db: Session, page: int = 1, pageSize: int = 10) -> Dict[str, Any]:
        """获取推荐视频列表"""
        # 验证分页参数
        if page < 1:
            page = 1
        if pageSize < 1 or pageSize > 50:
            pageSize = 10
        
        offset = (page - 1) * pageSize
        limit = pageSize
        
        # 尝试从Redis ZSET获取数据
        cache_key = "video:recommended:zset"
        total = redis_util.zcard(cache_key)
        
        if total > 0:
            # 从ZSET获取数据
            videos_data = redis_util.zrange(cache_key, offset, offset + limit - 1)
            if videos_data:
                total_pages = (total + pageSize - 1) // pageSize
                return {
                    "list": videos_data,
                    "total": total,
                    "page": page,
                    "pageSize": pageSize,
                    "totalPages": total_pages,
                    "fromCache": True
                }
        
        # 缓存未命中，查询数据库
        query = VideoController._get_video_detail_query(db)
        total = query.count()
        
        # 获取视频列表
        videos_with_user = query.order_by(desc(Video.collect_count)).offset(offset).limit(limit).all()
        
        # 转换为响应格式
        videos_data = []
        for video, username, nickname, avatar in videos_with_user:
            video_dict = {
                "id": video.id,
                "title": video.title,
                "description": video.description,
                "cover_url": video.cover_url,
                "video_url": video.video_url,
                "duration": video.duration,
                "category_id": video.category_id,
                "user_id": video.user_id,
                "username": username,
                "nickname": nickname,
                "avatar": avatar,
                "view_count": video.view_count,
                "like_count": video.like_count,
                "collect_count": video.collect_count,
                "comment_count": video.comment_count
            }
            videos_data.append(video_dict)
        
        # 如果是第一页，初始化缓存
        if page == 1:
            # 异步初始化缓存
            def init_cache():
                try:
                    # 获取更多数据用于初始化缓存
                    all_videos = query.order_by(desc(Video.collect_count)).limit(100).all()
                    videos_list = []
                    for video, username, nickname, avatar in all_videos:
                        video_dict = {
                            "id": video.id,
                            "title": video.title,
                            "description": video.description,
                            "cover_url": video.cover_url,
                            "video_url": video.video_url,
                            "duration": video.duration,
                            "category_id": video.category_id,
                            "user_id": video.user_id,
                            "username": username,
                            "nickname": nickname,
                            "avatar": avatar,
                            "view_count": video.view_count,
                            "like_count": video.like_count,
                            "collect_count": video.collect_count,
                            "comment_count": video.comment_count
                        }
                        videos_list.append(video_dict)
                    redis_util.init_video_zset(cache_key, videos_list, "collect_count")
                except Exception as e:
                    logger.error(f"初始化推荐视频缓存失败: {e}")
            
            threading.Thread(target=init_cache).start()
        
        total_pages = (total + pageSize - 1) // pageSize
        return {
            "list": videos_data,
            "total": total,
            "page": page,
            "pageSize": pageSize,
            "totalPages": total_pages,
            "fromCache": False
        }
    
    @staticmethod
    def get_hot_videos(db: Session, page: int = 1, pageSize: int = 10) -> Dict[str, Any]:
        """获取热门视频列表"""
        # 验证分页参数
        if page < 1:
            page = 1
        if pageSize < 1 or pageSize > 50:
            pageSize = 10
        
        offset = (page - 1) * pageSize
        limit = pageSize
        
        # 尝试从Redis ZSET获取数据
        cache_key = "video:hot:zset"
        total = redis_util.zcard(cache_key)
        
        if total > 0:
            # 从ZSET获取数据
            videos_data = redis_util.zrange(cache_key, offset, offset + limit - 1)
            if videos_data:
                total_pages = (total + pageSize - 1) // pageSize
                return {
                    "list": videos_data,
                    "total": total,
                    "page": page,
                    "pageSize": pageSize,
                    "totalPages": total_pages,
                    "fromCache": True
                }
        
        # 缓存未命中，查询数据库
        query = VideoController._get_video_detail_query(db)
        total = query.count()
        
        # 获取视频列表
        videos_with_user = query.order_by(desc(Video.view_count)).offset(offset).limit(limit).all()
        
        # 转换为响应格式
        videos_data = []
        for video, username, nickname, avatar in videos_with_user:
            video_dict = {
                "id": video.id,
                "title": video.title,
                "description": video.description,
                "cover_url": video.cover_url,
                "video_url": video.video_url,
                "duration": video.duration,
                "category_id": video.category_id,
                "user_id": video.user_id,
                "username": username,
                "nickname": nickname,
                "avatar": avatar,
                "view_count": video.view_count,
                "like_count": video.like_count,
                "collect_count": video.collect_count,
                "comment_count": video.comment_count
            }
            videos_data.append(video_dict)
        
        # 如果是第一页，初始化缓存
        if page == 1:
            # 异步初始化缓存
            def init_cache():
                try:
                    # 获取更多数据用于初始化缓存
                    all_videos = query.order_by(desc(Video.view_count)).limit(100).all()
                    videos_list = []
                    for video, username, nickname, avatar in all_videos:
                        video_dict = {
                            "id": video.id,
                            "title": video.title,
                            "description": video.description,
                            "cover_url": video.cover_url,
                            "video_url": video.video_url,
                            "duration": video.duration,
                            "category_id": video.category_id,
                            "user_id": video.user_id,
                            "username": username,
                            "nickname": nickname,
                            "avatar": avatar,
                            "view_count": video.view_count,
                            "like_count": video.like_count,
                            "collect_count": video.collect_count,
                            "comment_count": video.comment_count
                        }
                        videos_list.append(video_dict)
                    redis_util.init_video_zset(cache_key, videos_list, "view_count")
                except Exception as e:
                    logger.error(f"初始化热门视频缓存失败: {e}")
            
            threading.Thread(target=init_cache).start()
        
        total_pages = (total + pageSize - 1) // pageSize
        return {
            "list": videos_data,
            "total": total,
            "page": page,
            "pageSize": pageSize,
            "totalPages": total_pages,
            "fromCache": False
        }
    
    @staticmethod
    def get_latest_videos(db: Session, page: int = 1, pageSize: int = 10) -> Dict[str, Any]:
        """获取最新视频列表"""
        # 验证分页参数
        if page < 1:
            page = 1
        if pageSize < 1 or pageSize > 50:
            pageSize = 10
        
        # 尝试从缓存获取
        cache_key = f"video:latest:page:{page}:size:{pageSize}"
        cached_data = redis_util.get_cache(cache_key)
        if cached_data:
            return cached_data
        
        # 缓存未命中，查询数据库
        offset = (page - 1) * pageSize
        limit = pageSize
        
        query = VideoController._get_video_detail_query(db)
        total = query.count()
        
        # 获取视频列表
        videos_with_user = query.order_by(desc(Video.created_at)).offset(offset).limit(limit).all()
        
        # 转换为响应格式
        videos_data = []
        for video, username, nickname, avatar in videos_with_user:
            video_dict = {
                "id": video.id,
                "title": video.title,
                "description": video.description,
                "cover_url": video.cover_url,
                "video_url": video.video_url,
                "duration": video.duration,
                "category_id": video.category_id,
                "user_id": video.user_id,
                "username": username,
                "nickname": nickname,
                "avatar": avatar,
                "view_count": video.view_count,
                "like_count": video.like_count,
                "collect_count": video.collect_count,
                "comment_count": video.comment_count
            }
            videos_data.append(video_dict)
        
        total_pages = (total + pageSize - 1) // pageSize
        result = {
            "list": videos_data,
            "total": total,
            "page": page,
            "pageSize": pageSize,
            "totalPages": total_pages,
            "fromCache": False
        }
        
        # 设置缓存（10分钟）
        redis_util.set_cache(cache_key, result, 600)
        
        return result
    
    @staticmethod
    def get_slide_videos(db: Session) -> List[Dict[str, Any]]:
        """获取幻灯片视频（前5个热门视频）"""
        # 尝试从缓存获取
        cache_key = "video:slide"
        cached_data = redis_util.get_cache(cache_key)
        if cached_data:
            return cached_data
        
        # 缓存未命中，查询数据库
        query = VideoController._get_video_detail_query(db)
        videos_with_user = query.order_by(desc(Video.view_count)).limit(5).all()
        
        # 转换为响应格式
        videos_data = []
        for video, username, nickname, avatar in videos_with_user:
            video_dict = {
                "id": video.id,
                "title": video.title,
                "description": video.description,
                "cover_url": video.cover_url,
                "video_url": video.video_url,
                "duration": video.duration,
                "category_id": video.category_id,
                "user_id": video.user_id,
                "username": username,
                "nickname": nickname,
                "avatar": avatar,
                "view_count": video.view_count,
                "like_count": video.like_count,
                "collect_count": video.collect_count,
                "comment_count": video.comment_count
            }
            videos_data.append(video_dict)
        
        # 设置缓存（1小时）
        redis_util.set_cache(cache_key, videos_data, 3600)
        
        return videos_data
    
    @staticmethod
    def get_category_videos(db: Session, category_id: int, page: int = 1, pageSize: int = 10) -> Dict[str, Any]:
        """获取分类视频列表"""
        # 验证参数
        if category_id <= 0:
            raise ValueError("分类ID无效")
        if page < 1:
            page = 1
        if pageSize < 1 or pageSize > 50:
            pageSize = 10
        
        # 尝试从缓存获取
        cache_key = f"video:category:{category_id}:page:{page}:size:{pageSize}"
        cached_data = redis_util.get_cache(cache_key)
        if cached_data:
            return cached_data
        
        # 缓存未命中，查询数据库
        offset = (page - 1) * pageSize
        limit = pageSize
        
        query = VideoController._get_video_detail_query(db).filter(Video.category_id == category_id)
        total = query.count()
        
        # 获取视频列表
        videos_with_user = query.order_by(desc(Video.created_at)).offset(offset).limit(limit).all()
        
        # 转换为响应格式
        videos_data = []
        for video, username, nickname, avatar in videos_with_user:
            video_dict = {
                "id": video.id,
                "title": video.title,
                "description": video.description,
                "cover_url": video.cover_url,
                "video_url": video.video_url,
                "duration": video.duration,
                "category_id": video.category_id,
                "user_id": video.user_id,
                "username": username,
                "nickname": nickname,
                "avatar": avatar,
                "view_count": video.view_count,
                "like_count": video.like_count,
                "collect_count": video.collect_count,
                "comment_count": video.comment_count
            }
            videos_data.append(video_dict)
        
        total_pages = (total + pageSize - 1) // pageSize
        result = {
            "list": videos_data,
            "total": total,
            "page": page,
            "pageSize": pageSize,
            "totalPages": total_pages,
            "fromCache": False
        }
        
        # 设置缓存（10分钟）
        redis_util.set_cache(cache_key, result, 600)
        
        return result
    
    @staticmethod
    def get_video_detail(db: Session, video_id: int, user_id: Optional[int] = None) -> Optional[Dict[str, Any]]:
        """获取视频详情"""
        # 尝试从缓存获取
        cache_key = f"video:detail:{video_id}"
        cached_data = redis_util.get_cache(cache_key)
        
        # 如果有缓存且用户未登录，直接返回
        if cached_data and user_id is None:
            # 异步更新观看次数
            threading.Thread(target=lambda: redis_util.add_view_count(video_id)).start()
            return cached_data
        
        # 查询数据库
        query = db.query(
            Video,
            User.username,
            User.nickname,
            User.avatar,
            Category.name.label('category_name')
        ).join(
            User, Video.user_id == User.id
        ).join(
            Category, Video.category_id == Category.id
        ).filter(
            Video.id == video_id,
            Video.status == 1
        )
        
        result = query.first()
        if not result:
            return None
        
        video, username, nickname, avatar, category_name = result
        
        # 构建视频详情数据
        video_detail = {
            "id": video.id,
            "title": video.title,
            "description": video.description,
            "cover_url": video.cover_url,
            "video_url": video.video_url,
            "duration": video.duration,
            "category_id": video.category_id,
            "category_name": category_name,
            "user_id": video.user_id,
            "username": username,
            "nickname": nickname,
            "avatar": avatar,
            "view_count": video.view_count,
            "like_count": video.like_count,
            "collect_count": video.collect_count,
            "comment_count": video.comment_count,
            "is_liked": False,
            "is_collected": False
        }
        
        # 如果用户已登录，检查点赞和收藏状态
        if user_id:
            # 检查点赞状态
            like = db.query(Like).filter(
                Like.user_id == user_id,
                Like.video_id == video_id
            ).first()
            video_detail["is_liked"] = like is not None
            
            # 检查收藏状态
            favorite = db.query(Favorite).filter(
                Favorite.user_id == user_id,
                Favorite.video_id == video_id
            ).first()
            video_detail["is_collected"] = favorite is not None
        
        # 如果用户未登录，设置缓存
        if user_id is None:
            redis_util.set_cache(cache_key, video_detail, 600)  # 10分钟缓存
        
        # 异步更新观看次数
        threading.Thread(target=lambda: redis_util.add_view_count(video_id)).start()
        
        return video_detail


# 创建全局视频控制器实例
video_controller = VideoController()
